package com.niuwa.p2p.service.impl.messageTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.itextpdf.text.pdf.PdfStructTreeController.returnType;
import com.niuwa.p2p.core.enums.MessageTemplateEnum;
import com.niuwa.p2p.core.enums.MsgSourceEnum;
import com.niuwa.p2p.core.utils.StringUtil;
import com.niuwa.p2p.dao.message.MsgTempCfgDao;
import com.niuwa.p2p.dao.message.MsgTemplateDao;
import com.niuwa.p2p.entity.message.MsgTempCfg;
import com.niuwa.p2p.entity.message.MsgTempCfgKey;
import com.niuwa.p2p.entity.message.MsgTemplate;
import com.niuwa.p2p.service.messageTemplate.IMessageTemplateService;
import com.opensymphony.xwork2.ActionContext;

/**
 * @author futianliang
 * @date 2015年4月15日
 */
@Service
public class MessageTemplateServiceImpl implements IMessageTemplateService {
	@Autowired
	private MsgTemplateDao templateDao;
	@Autowired
	private MsgTempCfgDao msgTempCfgDao;

	@Override
	public Map<String, String> fetchMessageTemplateContentByType(MessageTemplateEnum templateEnum, String[] messageType, Map<MsgSourceEnum, Object> paras) {
		Map<String, String> map = new HashMap<String, String>();

		if (templateEnum == null) {
			map.put("content", "failed:暂不支持该模板，请在MessageTemplateEnum中先配置");
			return map;
		}
		// 根据id得到模板的对象
		MsgTemplate template = templateDao.selectByPrimaryKey(templateEnum.getCode());
		// String templatePath = "/" + templateEnum.getCode() + ".vm";

		if (paras == null) {
			map.put("content", template.getTempContent());
		} else {
			for (String str : messageType) {
				if (!template.getSendMethod().contains(str)) {
					map.put(str, "failed:此模板暂不支持此方式发送消息");
					continue;
				}
				String content = getContent(template.getTempContent(), paras);
				// 获取此类型的首尾
				content = fetchHeadAndFoot(content, str, template);
				map.put(str, content);
			}
		}
		return map;
	}

	private String getContent(String tempContent, Map<MsgSourceEnum, Object> paras) {
		if (paras == null) {
			return tempContent;
		}
		String rex = "\\[(.*?)\\]";
		Pattern p = Pattern.compile(rex);
		Matcher m = p.matcher(tempContent);
		StringBuilder sbBuilder = new StringBuilder();
		int start = 0;
		int end = 0;
		while (m.find()) {
			String value = m.group(1);
			String template = (String) paras.get(MsgSourceEnum.getEnumByInfo(value));
			int now = m.start();
			sbBuilder.append(tempContent.substring(start, now)).append("[").append(template).append("]");
			start = m.end();
			end = start;

		}
		sbBuilder.append(tempContent.substring(end));
		return sbBuilder.toString();
	}

	private String fetchHeadAndFoot(String content, String type, MsgTemplate template) {
		MsgTempCfgKey key = new MsgTempCfgKey();
		key.setSendMethod(type);
		key.setPlatformType(template.getPlatformType());
		MsgTempCfg cfg = msgTempCfgDao.selectByPrimaryKey(key);
		if (cfg != null) {
			if (!"无".equals(cfg.getHead())) {
				content = cfg.getHead() + content;
			}
			if (!"无".equals(cfg.getFoot())) {
				content = content + cfg.getFoot();
			}
		}
		return content;
	}

	private VelocityEngine getEngine() {
		InputStream is = this.getClass().getResourceAsStream("/velocity.properties");
		Properties properties = new Properties();
		try {
			properties.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		VelocityEngine ve = new VelocityEngine();
		ActionContext ac = ActionContext.getContext();
		HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
		ve.setApplicationAttribute("javax.servlet.ServletContext", request.getSession().getServletContext());
		ve.init(properties);
		return ve;
	}

	private void setContentByPara(VelocityContext context, Map<MsgSourceEnum, Object> paras) {
		if (paras != null) {
			for (MsgSourceEnum enum1 : paras.keySet()) {
				context.put(enum1.getKey(), paras.get(enum1));
			}
		}
	}

	private String getTemplateContent(String templateContentPath, Map<MsgSourceEnum, Object> paras) {
		VelocityEngine ve = this.getEngine();
		Template t = ve.getTemplate(templateContentPath);
		VelocityContext context = new VelocityContext();
		setContentByPara(context, paras);
		StringWriter writer = new StringWriter();
		t.merge(context, writer);
		if (!StringUtil.isEmpty(writer.toString())) {
			// System.out.println(writer.toString().trim());
			return writer.toString().trim();
		}
		return "";
	}

	public static void main(String[] args) {
		MessageTemplateServiceImpl entityImpl = new MessageTemplateServiceImpl();
		/*
		 * Map<String, Object> map =
		 * entityImpl.produceTemplateByExcel("E:\\消息通知模板列表20150415-V0.2.xlsx");
		 * List<MsgTemplate> templates = (List<MsgTemplate>) map.get("key"); for
		 * (MsgTemplate t : templates) { System.out.println(t.getTempNo() + "="
		 * + t.getTempName() + "=" + t.getSendMethod() + "=" +
		 * t.getPlatformType() + "=" + t.getTitle() + "=" + t.getMsgKind() + "="
		 * + t.getTempContent()); }
		 * 
		 */
		String string = "你们";
		System.out.println(string.matches("((你们|他的|我的),)*?(你们|他的|我的(,?))"));
		System.out.println(string.matches("([ABC],)*?([ABC](,?))"));
		//entityImpl.dealWithTemplateContent(null);
	}

	private String fetchTemplatePath() {
		File file = new File(getClass().getClassLoader().getResource("/").getPath());
		String tempFileString = "";
		if (file.exists()) {
			tempFileString = file.getParent() + "/content/template";
		}
		if (!StringUtil.isEmpty(tempFileString)) {
			File tempFile = new File(tempFileString);
			if (!tempFile.exists()) {
				tempFile.mkdirs();
				return tempFileString;
			}
		}
		return tempFileString;
	}

	@Override
	public Map<String, Object> produceTemplateByExcel(String filePath) {
		String[] items = { "模板编号", "模板名称", "发送方式", "平台", "触发条件", "标题", "大类", "内容" };
		int columnSuccessCount = 0;
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			InputStream input = new FileInputStream(filePath); // 建立输入流
			Workbook wb = null;
			// 根据文件格式(2003或者2007)来初始化
			if (filePath.endsWith("xlsx")) {
				wb = new XSSFWorkbook(input);
			} else {
				wb = new HSSFWorkbook(input);
			}
			List<MsgTemplate> templates = new ArrayList<MsgTemplate>();
			MsgTemplate template = null;
			Sheet sheet = wb.getSheetAt(0); // 获得第一个表单
			Iterator<Row> rows = sheet.rowIterator(); // 获得第一个表单的迭代器
			int rowNum = 0;
			while (rows.hasNext()) {
				Row row = rows.next(); // 获得行数据
				rowNum++;
				template = new MsgTemplate();
				// System.out.println("Row #" + row.getRowNum()); // 获得行号从0开始
				Iterator<Cell> cells = row.cellIterator(); // 获得第一行的迭代器
				String value = null;
				Object cellValue = null;
				int currentColumn = 0;
				while (cells.hasNext()) {
					currentColumn++;
					Cell cell = cells.next();
					if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
						cellValue = cell.getNumericCellValue();
					} else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
						cellValue = cell.getStringCellValue();
					} else if (cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
						cellValue = cell.getBooleanCellValue();
					} else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
						cellValue = cell.getCellFormula();
					}

					if (cellValue != null) {
						value = String.valueOf(cellValue);
					}
					if (items[0].equals(value) && currentColumn == 1) {
						columnSuccessCount++;
					} else if (items[1].equals(value) && currentColumn == 2) {
						columnSuccessCount++;
					} else if (items[2].equals(value) && currentColumn == 3) {
						columnSuccessCount++;
					} else if (items[3].equals(value) && currentColumn == 4) {
						columnSuccessCount++;
					} else if (items[4].equals(value) && currentColumn == 5) {
						columnSuccessCount++;
					} else if (items[5].equals(value) && currentColumn == 6) {
						columnSuccessCount++;
					} else if (items[6].equals(value) && currentColumn == 7) {
						columnSuccessCount++;
					} else if (items[7].equals(value) && currentColumn == 8) {
						columnSuccessCount++;
					}

					if (currentColumn == 1) {
						template.setTempNo(value);
					} else if (currentColumn == 2) {
						template.setTempName(value);
					} else if (currentColumn == 3) {
						value = value.replaceAll("短信", "SMS").replaceAll("站内信", "IN_MSG").replaceAll("邮件", "EMAIL");
						template.setSendMethod(value);
					} else if (currentColumn == 4) {
						template.setPlatformType(value);
					} else if (currentColumn == 5) {
						template.setTriggerCondition(value);
					} else if (currentColumn == 6) {
						template.setTitle(value);
					} else if (currentColumn == 7) {
						template.setMsgKind(value);
					} else if (currentColumn == 8) {
						template.setTempContent(value);
					}
				}
				template.setCreateTime(new Date());
				if (rowNum != 1) {
					templates.add(template);
				}
			}
			if (columnSuccessCount != items.length) {
				map.put("key", "excel列名有错或者列名的顺序错误，请检查列");
				return map;
			}
			String state = checkExcel(templates);
			if (state == null) {
				map.put("key", templates);
			} else {
				map.put("key", state);
			}

		} catch (Exception ex) {
			map.put("key", "读取文件内容失败，请确认文件内容是xls或xlsx的");
		}
		return map;
	}

	private String checkExcel(List<MsgTemplate> templates) {
		String state = null;
		Map<String, MsgTemplate> map = new HashMap<String, MsgTemplate>();
		for (MsgTemplate t : templates) {
			if (!map.containsKey(t.getTempNo())) {
				map.put(t.getTempNo(), t);
			} else {
				state = "重复的模板编号：" + t.getTempNo();
			}
			if (!map.containsKey(t.getTempName())) {
				map.put(t.getTempName(), t);
			} else {
				state = "重复的模板名称：" + t.getTempName();
			}
		}
		return state;
	}

	@Override
	public void addMessageTemplateBatch(List<MsgTemplate> templates, Long cusId) {
		/*
		 * String path = fetchTemplatePath(); File file = null; File tempFile =
		 * null; if (!StringUtil.isEmpty(path)) { file = new File(path);
		 * tempFile = file; } if (file.isDirectory()) { try {
		 * FileUtils.deleteDirectory(file); } catch (IOException e) { // TODO
		 * Auto-generated catch block e.printStackTrace(); } }
		 * 
		 * for (MsgTemplate t : templates) { try { FileUtils.write(new
		 * File(tempFile.getAbsolutePath() + "/" + t.getTempNo() + ".vm"),
		 * dealWithTemplateContent("#*" + t.getTempName() + "*#" + "\r\n" +
		 * t.getTempContent()), "UTF-8"); } catch (IOException e) { // TODO
		 * Auto-generated catch block e.printStackTrace(); }
		 * t.setCreator(cusId); t.setTempContent(t.getTempNo() + ".vm"); }
		 */
		templateDao.truncate();
		templateDao.addMessageTemplateBatch(templates);
	}

	private String dealWithTemplateContent(String tempContent) {
		String rex = "\\[(.*?)\\]";
		Pattern p = Pattern.compile(rex);
		Matcher m = p.matcher(tempContent);
		StringBuilder sbBuilder = new StringBuilder();
		int start = 0;
		int end = 0;
		while (m.find()) {
			String value = m.group(1);
			String key = MsgSourceEnum.getKeyByInfo(value);
			String template = "#if($" + key + ")${" + key + "}#else[" + value + "]#end";
			int now = m.start();
			sbBuilder.append(tempContent.substring(start, now)).append(template);
			start = m.end();
			end = start;

		}
		sbBuilder.append(tempContent.substring(end));
		return sbBuilder.toString();
	}

	@Override
	public void truncate() {
		templateDao.truncate();
	}

	@Override
	public List<MsgTemplate> getMessageTemplateList(Map<String, Object> paras) {
		// TODO Auto-generated method stub
		return templateDao.getMessageTemplateList(paras);
	}

	@Override
	public int getMessageTemplateCount(Map<String, Object> paras) {
		// TODO Auto-generated method stub
		return templateDao.getMessageTemplateCount(paras);
	}

	@Override
	public MsgTemplate selectByPrimaryKey(String tempNo) {
		// TODO Auto-generated method stub
		return templateDao.selectByPrimaryKey(tempNo);
	}
}
